/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package actuatedocumentor;

import java.util.ArrayList;

/**
 *
 * @author Richard
 */
public class VersionChange {

    private OrderedHashMap classChangeMethodAdded;
    private OrderedHashMap classChangeMethodRemoved;
    private OrderedHashMap classChangeMethodChanged;
    private OrderedHashMap classRemoved;
    private OrderedHashMap classAdded;
    private ArrayList globalRemoved;
    private ArrayList globalAdded;
    private ArrayList libraryRemoved;
    private ArrayList libraryAdded;

    public VersionChange() {
        classChangeMethodAdded = new OrderedHashMap();//
        classChangeMethodRemoved = new OrderedHashMap();//
        classChangeMethodChanged = new OrderedHashMap();//


        classRemoved = new OrderedHashMap();//
        classAdded = new OrderedHashMap();//



        globalRemoved = new ArrayList();
        globalAdded = new ArrayList();

        libraryRemoved = new ArrayList();
        libraryAdded = new ArrayList();

    }

    public OrderedHashMap getClassAdded() {
        return classAdded;
    }

    public OrderedHashMap getClassChangeMethodAdded() {
        return classChangeMethodAdded;
    }

    public OrderedHashMap getClassChangeMethodChanged() {
        return classChangeMethodChanged;
    }

    public OrderedHashMap getClassChangeMethodRemoved() {
        return classChangeMethodRemoved;
    }

    public OrderedHashMap getClassRemoved() {
        return classRemoved;
    }

    
    
    public void doChecks(ReportVersion currentVersion,ReportVersion lastVersion){
        if(lastVersion==null){
            this.classAdded = (OrderedHashMap) currentVersion.getClasses().clone();
        }else{
        this.classChangeRemove(currentVersion, lastVersion);
        this.classChangeAdd(currentVersion, lastVersion);
        }
    } 
    
    public void classChangeMethodRemove(ActuateClass currentClass, ActuateClass lastClass) {
        ArrayList lastMethods = lastClass.getMethods().getArrayList();
        OrderedHashMap currentMethods = currentClass.getMethods();
        for (int i = 0; i < lastMethods.size(); i++) {
            ActuateClass newMethodClass;
            if (currentMethods.containsKey(((MethodDetails) lastMethods.get(i)).getMethodName())) {
            //no change
            } else {
                //removal required
                MethodDetails mdtemp = (MethodDetails) lastMethods.get(i);

                if (classChangeMethodRemoved.containsKey(currentClass.getClassIdentifier())) {
                    //Other methods from this class have been edited

                    newMethodClass = (ActuateClass) classChangeMethodRemoved.get(currentClass.getClassIdentifier());
                    newMethodClass.addMethod(mdtemp.getMethodName(), mdtemp.getMethodCode());

                } else {
                    ActuateClass tempClass = new ActuateClass();
                    tempClass.setClassIdentifier(lastClass.getClassIdentifier());
                    tempClass.setClassname(lastClass.getClassname());
                    tempClass.setSuperclassname(lastClass.getSuperclassname());
                    tempClass.addMethod(mdtemp.getMethodName(), mdtemp.getMethodCode());
                    classChangeMethodRemoved.put(tempClass.getClassIdentifier(), tempClass);

                }
            }
        }

    }

    public void classChangeMethodAddOrChange(ActuateClass currentClass, ActuateClass lastClass) {
        ArrayList currentMethods = currentClass.getMethods().getArrayList();
        OrderedHashMap lastMethods = lastClass.getMethods();
        for (int i = 0; i < currentMethods.size(); i++) {
            ActuateClass newMethodClass;
            if (lastMethods.containsKey(((MethodDetails) currentMethods.get(i)).getMethodName())) {
                MethodDetails md = (MethodDetails) lastMethods.get(((MethodDetails) currentMethods.get(i)).getMethodName());
                MethodDetails mdCurr = (MethodDetails) currentMethods.get(i);
                //call to check for method change
                if (md.getMethodCode().compareTo(mdCurr.getMethodCode()) == 0) {
                //no change
                } else {
                    //method changed
                    if (classChangeMethodChanged.containsKey(currentClass.getClassIdentifier())) {
                        //Other methods from this class have been edited
                        newMethodClass = (ActuateClass) classChangeMethodChanged.get(currentClass.getClassIdentifier());
                        ((MethodDetails) newMethodClass.getMethods().get(mdCurr.getMethodName())).setMethodCode(mdCurr.getMethodCode());

                    } else {
                        ActuateClass tempClass = new ActuateClass();
                        tempClass.setClassIdentifier(currentClass.getClassIdentifier());
                        tempClass.setClassname(currentClass.getClassname());
                        tempClass.setSuperclassname(currentClass.getSuperclassname());
                        tempClass.addMethod(mdCurr.getMethodName(), mdCurr.getMethodCode());
                        classChangeMethodChanged.put(tempClass.getClassIdentifier(), tempClass);

                    }



                }


            } else {
                //new Method in existing class
                MethodDetails mdAdd = (MethodDetails) currentMethods.get(i);

                if (classChangeMethodAdded.containsKey(currentClass.getClassIdentifier())) {
                    //Other methods from this class have been edited
                    newMethodClass = (ActuateClass) classChangeMethodAdded.get(currentClass.getClassIdentifier());
                    newMethodClass.addMethod(mdAdd.getMethodName(), mdAdd.getMethodCode());
                } else {
                    //first edit to class
                    newMethodClass = new ActuateClass();
                    newMethodClass.setClassIdentifier(currentClass.getClassIdentifier());
                    newMethodClass.setClassname(currentClass.getClassname());
                    newMethodClass.setSuperclassname(currentClass.getSuperclassname());
                    newMethodClass.addMethod(mdAdd.getMethodName(), mdAdd.getMethodCode());
                    this.classChangeMethodAdded.put(currentClass.getClassIdentifier(), newMethodClass);
                }


            }

        }
    }

    public void classChangeRemove(ReportVersion currentReportVersion, ReportVersion lastReportVersion) {
        ArrayList lastRv = lastReportVersion.getClasses().getArrayList();
        OrderedHashMap currRv = currentReportVersion.getClasses();

        for (int i = 0; i < lastRv.size(); i++) {
            if (currRv.containsKey(((ActuateClass) lastRv.get(i)).getClassIdentifier())) {
            //call to check for method change
            } else {
                //new class with code
                this.classRemoved.put((((ActuateClass) lastRv.get(i)).getClassIdentifier()), ((ActuateClass) lastRv.get(i)));
            }

        }
    }

    public void classChangeAdd(ReportVersion currentReportVersion, ReportVersion lastReportVersion) {
        ArrayList currRv = currentReportVersion.getClasses().getArrayList();
        OrderedHashMap lastRv = lastReportVersion.getClasses();

        for (int i = 0; i < currRv.size(); i++) {
            if (lastRv.containsKey(((ActuateClass) currRv.get(i)).getClassIdentifier())) {
            //call to check for method change
                this.classChangeMethodAddOrChange(((ActuateClass) currRv.get(i)), (ActuateClass)lastRv.get(((ActuateClass) currRv.get(i)).getClassIdentifier()));
                this.classChangeMethodRemove(((ActuateClass) currRv.get(i)), (ActuateClass)lastRv.get(((ActuateClass) currRv.get(i)).getClassIdentifier()));
            } else {
                //new class with code
                this.classAdded.put((((ActuateClass) currRv.get(i)).getClassIdentifier()), ((ActuateClass) currRv.get(i)));
            }

        }
    }
}
